package errcode

import (
	pb "go-programming-tour-book/tag-service/proto"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type Status struct {
	*status.Status
}

// FromError 服务自身在处理 err 时，获取错误类型
func FromError(err error) *Status {
	s, _ := status.FromError(err)
	return &Status{Status: s}
}

func TogRPCError(err *Error) error {
	//将原始业务错误码放进 Details 中
	pbErr := &pb.Error{Code: int32(err.Code()), Message: err.Msg()}
	//除了将原始业务错误码放进 Details 中，还可以将其他信息也放进去（在函数签名改为：func TogRPCError(err *Error, msg string) error）
	//pbErr := &pb.Error{Code: int32(err.Code()), Message: msg}
	s, _ := status.New(ToRPCCode(err.Code()), err.Msg()).WithDetails(pbErr)
	return s.Err()
}

func ToRPCCode(code int) codes.Code {
	var statusCode codes.Code
	switch code {
	case Fail.Code():
		statusCode = codes.Internal
	case InvalidParam.Code():
		statusCode = codes.InvalidArgument
	case Unauthorized.Code():
		statusCode = codes.Unauthenticated
	case AccessDenied.Code():
		statusCode = codes.PermissionDenied
	case DeadlineExceeded.Code():
		statusCode = codes.DeadlineExceeded
	case NotFound.Code():
		statusCode = codes.NotFound
	case LimitExceed.Code():
		statusCode = codes.ResourceExhausted
	case MethodNotAllowed.Code():
		statusCode = codes.Unimplemented
	default:
		statusCode = codes.Unknown
	}
	return statusCode
}
